package com.vecspace.security;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import com.vecspace.security.proxy.service.LoginManager;
import com.vecspace.sso.entity.UserBase;
import com.vecspace.utils.log.HLogger;

public class UserCache {
	private static UserCache userCache = null;
	private static Object lockLoadingObject = new Object();
	private Map<String, UserEx> usersMap = new HashMap<String, UserEx>();
	private List<UserBase> userList = new ArrayList<UserBase>();
	
	public static synchronized UserCache getInstance(){
		if(userCache == null){
			userCache = new UserCache();
		}
		return userCache;
	}
	
	//private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	 
	private UserCache(){
		init();
	}
	
	private void init(){
		loadAllUsers();
		Calendar nowTime = Calendar.getInstance();
		nowTime.add(Calendar.MINUTE, 3);
		Timer timer = new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {//每3分钟刷新一次数据
			@Override
			public void run() {
				List<UserBase> users = null;
				try {
					users = LoginManager.getAllUsers();
				} catch (Exception e1) {
					HLogger.DEFAULT().error(e1.getMessage());
					e1.printStackTrace();
				}
				if(users == null)return;
				Collections.sort(users, new Comparator<UserBase>(){
					 public int compare(UserBase user1, UserBase user2) {
						 	if(user1 == null || user1.getLoginId() == null) return -1;
						 	else if(user2 == null || user2.getLoginId() == null) return 1;
						 	else return user1.getLoginId().compareTo(user2.getLoginId());
			            }
				});
				
				synchronized (lockLoadingObject) {
					try {							
						usersMap.clear();
						userList.clear();
						for (UserBase user : users) {
							UserEx userEx = new UserEx(user);
							usersMap.put(user.getLoginId(), userEx);
						}						
						userList.addAll(users);
						HLogger.DEFAULT().info("加载并缓存的用户数："+users.size());
						 
					} catch (Exception e) {
						HLogger.DEFAULT().error(e.getMessage());
					}
				}
			}
		}, nowTime.getTime(), 3*60*1000);// 24*3600*1000
	}
		
	/**重新加载所有的用户
	 * @author: wanghua
	 */
	private void loadAllUsers(){		 
		synchronized (lockLoadingObject) {
			try {
				List<UserBase> users = LoginManager.getAllUsers();
				if(users == null)return;
				Collections.sort(users, new Comparator<UserBase>(){
					 public int compare(UserBase user1, UserBase user2) {
						 	if(user1 == null || user1.getLoginId() == null) return -1;
						 	else if(user2 == null || user2.getLoginId() == null) return 1;
						 	else return user1.getLoginId().compareTo(user2.getLoginId());
			            }
				});
				usersMap.clear();
				userList.clear();
				for (UserBase user : users) {
					UserEx userEx = new UserEx(user);
					usersMap.put(user.getLoginId(), userEx);
				}				
				userList.addAll(users);
				HLogger.DEFAULT().info("加载并缓存的用户数："+users.size());
				 
			} catch (Exception e) {
				HLogger.DEFAULT().error(e.getMessage());
			}
		}
	}
	
	/**获取所有的用户。
	 * 缓存中会保存所有用户的信息，并且每天全部重新加载一次
	 * @return 
	 * @author: wanghua
	 */
	public List<UserBase> getAllUsers(){
		synchronized (lockLoadingObject) {				
			List<UserBase> allUsers = new ArrayList<UserBase>();
			allUsers.addAll(userList);
			return allUsers;		
		}
	}
	
	/**从缓存中获取用户信息。
	 * 1、缓存有效期为当天，超出当天的缓存User不在可用。
	 * 2、如果缓存中不存在loginId，则从后台服务中查询该User
	 * @param loginId
	 * @return 
	 * @author: wanghua
	 */
	public UserBase getUser(String loginId) {
		if(loginId == null || loginId.length() == 0)return null;
		UserEx userEx = null;
		if(usersMap.size() == 0){
			this.loadAllUsers();
		}
		synchronized (lockLoadingObject) {	
			userEx = usersMap.get(loginId);
		}

		if (userEx == null) {
			//readWriteLock.writeLock().lock();		
							
			try {
				UserBase user = LoginManager.getUserBaseInfo(loginId);
				userEx = new UserEx(user);
				synchronized(lockLoadingObject){
					usersMap.put(loginId, userEx);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				//readWriteLock.writeLock().unlock();
			}		
		}
		if (userEx != null)
			return userEx.user;
		else
			return null;
		
	}
	
	public String getUserName(String loginId){
		UserBase user = this.getUser(loginId);
		if(user != null)return user.getUserName();
		else return null;
	}
	
	public String getUserEmail(String loginId){
		UserBase user = this.getUser(loginId);
		if(user != null)return user.getEmail();
		else return null;
	}
	
	public void reload(){
		loadAllUsers();
	}
	
	class UserEx{
		public UserEx(){
			
		}
		public UserEx(UserBase user){
			this.user = user;
		}
		public UserBase user;
		/**缓存创建时间*/
		public Calendar cacheTime = Calendar.getInstance();
	}
}
